home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / lxml / doctestcompare.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  14KB  |  535 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from lxml import etree
  5. import sys
  6. import re
  7. import doctest
  8. import cgi
  9. __all__ = [
  10.     'PARSE_HTML',
  11.     'PARSE_XML',
  12.     'NOPARSE_MARKUP',
  13.     'LXMLOutputChecker',
  14.     'LHTMLOutputChecker',
  15.     'install',
  16.     'temp_install']
  17.  
  18. try:
  19.     _basestring = basestring
  20. except NameError:
  21.     _basestring = (str, bytes)
  22.  
  23. _IS_PYTHON_3 = sys.version_info[0] >= 3
  24. PARSE_HTML = doctest.register_optionflag('PARSE_HTML')
  25. PARSE_XML = doctest.register_optionflag('PARSE_XML')
  26. NOPARSE_MARKUP = doctest.register_optionflag('NOPARSE_MARKUP')
  27. OutputChecker = doctest.OutputChecker
  28.  
  29. def strip(v):
  30.     if v is None:
  31.         return None
  32.     else:
  33.         return v.strip()
  34.  
  35.  
  36. def norm_whitespace(v):
  37.     return _norm_whitespace_re.sub(' ', v)
  38.  
  39. _html_parser = etree.HTMLParser(recover = False, remove_blank_text = True)
  40.  
  41. def html_fromstring(html):
  42.     return etree.fromstring(html, _html_parser)
  43.  
  44. _repr_re = re.compile('^<[^>]+ (at|object) ')
  45. _norm_whitespace_re = re.compile('[ \\t\\n][ \\t\\n]+')
  46.  
  47. class LXMLOutputChecker(OutputChecker):
  48.     empty_tags = ('param', 'img', 'area', 'br', 'basefont', 'input', 'base', 'meta', 'link', 'col')
  49.     
  50.     def get_default_parser(self):
  51.         return etree.XML
  52.  
  53.     
  54.     def check_output(self, want, got, optionflags):
  55.         alt_self = getattr(self, '_temp_override_self', None)
  56.         if alt_self is not None:
  57.             super_method = self._temp_call_super_check_output
  58.             self = alt_self
  59.         else:
  60.             super_method = OutputChecker.check_output
  61.         parser = self.get_parser(want, got, optionflags)
  62.         if not parser:
  63.             return super_method(self, want, got, optionflags)
  64.         
  65.         
  66.         try:
  67.             want_doc = parser(want)
  68.         except etree.XMLSyntaxError:
  69.             return False
  70.  
  71.         
  72.         try:
  73.             got_doc = parser(got)
  74.         except etree.XMLSyntaxError:
  75.             return False
  76.  
  77.         return self.compare_docs(want_doc, got_doc)
  78.  
  79.     
  80.     def get_parser(self, want, got, optionflags):
  81.         parser = None
  82.         if NOPARSE_MARKUP & optionflags:
  83.             return None
  84.         
  85.         if PARSE_HTML & optionflags:
  86.             parser = html_fromstring
  87.         elif PARSE_XML & optionflags:
  88.             parser = etree.XML
  89.         elif want.strip().lower().startswith('<html') and got.strip().startswith('<html'):
  90.             parser = html_fromstring
  91.         elif self._looks_like_markup(want) and self._looks_like_markup(got):
  92.             parser = self.get_default_parser()
  93.         
  94.         return parser
  95.  
  96.     
  97.     def _looks_like_markup(self, s):
  98.         s = s.strip()
  99.         if s.startswith('<'):
  100.             pass
  101.         return not _repr_re.search(s)
  102.  
  103.     
  104.     def compare_docs(self, want, got):
  105.         if not self.tag_compare(want.tag, got.tag):
  106.             return False
  107.         
  108.         if not self.text_compare(want.text, got.text, True):
  109.             return False
  110.         
  111.         if not self.text_compare(want.tail, got.tail, True):
  112.             return False
  113.         
  114.         if 'any' not in want.attrib:
  115.             want_keys = sorted(want.attrib.keys())
  116.             got_keys = sorted(got.attrib.keys())
  117.             if want_keys != got_keys:
  118.                 return False
  119.             
  120.             for key in want_keys:
  121.                 if not self.text_compare(want.attrib[key], got.attrib[key], False):
  122.                     return False
  123.                     continue
  124.             
  125.         
  126.         if want.text != '...' or len(want):
  127.             want_children = list(want)
  128.             got_children = list(got)
  129.             while want_children or got_children:
  130.                 if not want_children or not got_children:
  131.                     return False
  132.                 
  133.                 want_first = want_children.pop(0)
  134.                 got_first = got_children.pop(0)
  135.                 if not self.compare_docs(want_first, got_first):
  136.                     return False
  137.                 
  138.                 if not got_children and want_first.tail == '...':
  139.                     break
  140.                     continue
  141.         
  142.         return True
  143.  
  144.     
  145.     def text_compare(self, want, got, strip):
  146.         if not want:
  147.             pass
  148.         want = ''
  149.         if not got:
  150.             pass
  151.         got = ''
  152.         if strip:
  153.             want = norm_whitespace(want).strip()
  154.             got = norm_whitespace(got).strip()
  155.         
  156.         want = '^%s$' % re.escape(want)
  157.         want = want.replace('\\.\\.\\.', '.*')
  158.         if re.search(want, got):
  159.             return True
  160.         else:
  161.             return False
  162.  
  163.     
  164.     def tag_compare(self, want, got):
  165.         if want == 'any':
  166.             return True
  167.         
  168.         if not isinstance(want, _basestring) or not isinstance(got, _basestring):
  169.             return want == got
  170.         
  171.         if not want:
  172.             pass
  173.         want = ''
  174.         if not got:
  175.             pass
  176.         got = ''
  177.         if want.startswith('{...}'):
  178.             return want.split('}')[-1] == got.split('}')[-1]
  179.         else:
  180.             return want == got
  181.  
  182.     
  183.     def output_difference(self, example, got, optionflags):
  184.         want = example.want
  185.         parser = self.get_parser(want, got, optionflags)
  186.         errors = []
  187.         if parser is not None:
  188.             
  189.             try:
  190.                 want_doc = parser(want)
  191.             except etree.XMLSyntaxError:
  192.                 e = sys.exc_info()[1]
  193.                 errors.append('In example: %s' % e)
  194.  
  195.             
  196.             try:
  197.                 got_doc = parser(got)
  198.             except etree.XMLSyntaxError:
  199.                 e = sys.exc_info()[1]
  200.                 errors.append('In actual output: %s' % e)
  201.             except:
  202.                 None<EXCEPTION MATCH>etree.XMLSyntaxError
  203.             
  204.  
  205.         None<EXCEPTION MATCH>etree.XMLSyntaxError
  206.         if parser is None or errors:
  207.             value = OutputChecker.output_difference(self, example, got, optionflags)
  208.             if errors:
  209.                 errors.append(value)
  210.                 return '\n'.join(errors)
  211.             else:
  212.                 return value
  213.         
  214.         html = parser is html_fromstring
  215.         diff_parts = []
  216.         diff_parts.append('Expected:')
  217.         diff_parts.append(self.format_doc(want_doc, html, 2))
  218.         diff_parts.append('Got:')
  219.         diff_parts.append(self.format_doc(got_doc, html, 2))
  220.         diff_parts.append('Diff:')
  221.         diff_parts.append(self.collect_diff(want_doc, got_doc, html, 2))
  222.         return '\n'.join(diff_parts)
  223.  
  224.     
  225.     def html_empty_tag(self, el, html = True):
  226.         if not html:
  227.             return False
  228.         
  229.         if el.tag not in self.empty_tags:
  230.             return False
  231.         
  232.         if el.text or len(el):
  233.             return False
  234.         
  235.         return True
  236.  
  237.     
  238.     def format_doc(self, doc, html, indent, prefix = ''):
  239.         parts = []
  240.         if not len(doc):
  241.             parts.append(' ' * indent)
  242.             parts.append(prefix)
  243.             parts.append(self.format_tag(doc))
  244.             if not self.html_empty_tag(doc, html):
  245.                 if strip(doc.text):
  246.                     parts.append(self.format_text(doc.text))
  247.                 
  248.                 parts.append(self.format_end_tag(doc))
  249.             
  250.             if strip(doc.tail):
  251.                 parts.append(self.format_text(doc.tail))
  252.             
  253.             parts.append('\n')
  254.             return ''.join(parts)
  255.         
  256.         parts.append(' ' * indent)
  257.         parts.append(prefix)
  258.         parts.append(self.format_tag(doc))
  259.         if not self.html_empty_tag(doc, html):
  260.             parts.append('\n')
  261.             if strip(doc.text):
  262.                 parts.append(' ' * indent)
  263.                 parts.append(self.format_text(doc.text))
  264.                 parts.append('\n')
  265.             
  266.             for el in doc:
  267.                 parts.append(self.format_doc(el, html, indent + 2))
  268.             
  269.             parts.append(' ' * indent)
  270.             parts.append(self.format_end_tag(doc))
  271.             parts.append('\n')
  272.         
  273.         if strip(doc.tail):
  274.             parts.append(' ' * indent)
  275.             parts.append(self.format_text(doc.tail))
  276.             parts.append('\n')
  277.         
  278.         return ''.join(parts)
  279.  
  280.     
  281.     def format_text(self, text, strip = True):
  282.         if text is None:
  283.             return ''
  284.         
  285.         if strip:
  286.             text = text.strip()
  287.         
  288.         return cgi.escape(text, 1)
  289.  
  290.     
  291.     def format_tag(self, el):
  292.         attrs = []
  293.         if isinstance(el, etree.CommentBase):
  294.             return '<!--'
  295.         
  296.         for name, value in sorted(el.attrib.items()):
  297.             attrs.append('%s="%s"' % (name, self.format_text(value, False)))
  298.         
  299.         if not attrs:
  300.             return '<%s>' % el.tag
  301.         
  302.         return '<%s %s>' % (el.tag, ' '.join(attrs))
  303.  
  304.     
  305.     def format_end_tag(self, el):
  306.         if isinstance(el, etree.CommentBase):
  307.             return '-->'
  308.         
  309.         return '</%s>' % el.tag
  310.  
  311.     
  312.     def collect_diff(self, want, got, html, indent):
  313.         parts = []
  314.         if not len(want) and not len(got):
  315.             parts.append(' ' * indent)
  316.             parts.append(self.collect_diff_tag(want, got))
  317.             if not self.html_empty_tag(got, html):
  318.                 parts.append(self.collect_diff_text(want.text, got.text))
  319.                 parts.append(self.collect_diff_end_tag(want, got))
  320.             
  321.             parts.append(self.collect_diff_text(want.tail, got.tail))
  322.             parts.append('\n')
  323.             return ''.join(parts)
  324.         
  325.         parts.append(' ' * indent)
  326.         parts.append(self.collect_diff_tag(want, got))
  327.         parts.append('\n')
  328.         if strip(want.text) or strip(got.text):
  329.             parts.append(' ' * indent)
  330.             parts.append(self.collect_diff_text(want.text, got.text))
  331.             parts.append('\n')
  332.         
  333.         want_children = list(want)
  334.         got_children = list(got)
  335.         while want_children or got_children:
  336.             if not want_children:
  337.                 parts.append(self.format_doc(got_children.pop(0), html, indent + 2, '-'))
  338.                 continue
  339.             
  340.             if not got_children:
  341.                 parts.append(self.format_doc(want_children.pop(0), html, indent + 2, '+'))
  342.                 continue
  343.             
  344.             parts.append(self.collect_diff(want_children.pop(0), got_children.pop(0), html, indent + 2))
  345.         parts.append(' ' * indent)
  346.         parts.append(self.collect_diff_end_tag(want, got))
  347.         parts.append('\n')
  348.         if strip(want.tail) or strip(got.tail):
  349.             parts.append(' ' * indent)
  350.             parts.append(self.collect_diff_text(want.tail, got.tail))
  351.             parts.append('\n')
  352.         
  353.         return ''.join(parts)
  354.  
  355.     
  356.     def collect_diff_tag(self, want, got):
  357.         if not self.tag_compare(want.tag, got.tag):
  358.             tag = '%s (got: %s)' % (want.tag, got.tag)
  359.         else:
  360.             tag = got.tag
  361.         attrs = []
  362.         if not want.tag == 'any':
  363.             pass
  364.         any = 'any' in want.attrib
  365.         for name, value in sorted(got.attrib.items()):
  366.             if name not in want.attrib and not any:
  367.                 attrs.append('-%s="%s"' % (name, self.format_text(value, False)))
  368.                 continue
  369.             if name in want.attrib:
  370.                 text = self.collect_diff_text(value, want.attrib[name], False)
  371.             else:
  372.                 text = self.format_text(value, False)
  373.             attrs.append('%s="%s"' % (name, text))
  374.         
  375.         if not any:
  376.             for name, value in sorted(want.attrib.items()):
  377.                 if name in got.attrib:
  378.                     continue
  379.                 
  380.                 attrs.append('+%s="%s"' % (name, self.format_text(value, False)))
  381.             
  382.         
  383.         if attrs:
  384.             tag = '<%s %s>' % (tag, ' '.join(attrs))
  385.         else:
  386.             tag = '<%s>' % tag
  387.         return tag
  388.  
  389.     
  390.     def collect_diff_end_tag(self, want, got):
  391.         if want.tag != got.tag:
  392.             tag = '%s (got: %s)' % (want.tag, got.tag)
  393.         else:
  394.             tag = got.tag
  395.         return '</%s>' % tag
  396.  
  397.     
  398.     def collect_diff_text(self, want, got, strip = True):
  399.         if self.text_compare(want, got, strip):
  400.             if not got:
  401.                 return ''
  402.             
  403.             return self.format_text(got, strip)
  404.         
  405.         text = '%s (got: %s)' % (want, got)
  406.         return self.format_text(text, strip)
  407.  
  408.  
  409.  
  410. class LHTMLOutputChecker(LXMLOutputChecker):
  411.     
  412.     def get_default_parser(self):
  413.         return html_fromstring
  414.  
  415.  
  416.  
  417. def install(html = False):
  418.     if html:
  419.         doctest.OutputChecker = LHTMLOutputChecker
  420.     else:
  421.         doctest.OutputChecker = LXMLOutputChecker
  422.  
  423.  
  424. def temp_install(html = False, del_module = None):
  425.     if html:
  426.         Checker = LHTMLOutputChecker
  427.     else:
  428.         Checker = LXMLOutputChecker
  429.     frame = _find_doctest_frame()
  430.     dt_self = frame.f_locals['self']
  431.     checker = Checker()
  432.     old_checker = dt_self._checker
  433.     dt_self._checker = checker
  434.     if _IS_PYTHON_3:
  435.         check_func = frame.f_locals['check'].__func__
  436.         checker_check_func = checker.check_output.__func__
  437.     else:
  438.         check_func = frame.f_locals['check'].im_func
  439.         checker_check_func = checker.check_output.im_func
  440.     doctest.etree = etree
  441.     _RestoreChecker(dt_self, old_checker, checker, check_func, checker_check_func, del_module)
  442.  
  443.  
  444. class _RestoreChecker(object):
  445.     
  446.     def __init__(self, dt_self, old_checker, new_checker, check_func, clone_func, del_module):
  447.         self.dt_self = dt_self
  448.         self.checker = old_checker
  449.         self.checker._temp_call_super_check_output = self.call_super
  450.         self.checker._temp_override_self = new_checker
  451.         self.check_func = check_func
  452.         self.clone_func = clone_func
  453.         self.del_module = del_module
  454.         self.install_clone()
  455.         self.install_dt_self()
  456.  
  457.     
  458.     def install_clone(self):
  459.         if _IS_PYTHON_3:
  460.             self.func_code = self.check_func.__code__
  461.             self.func_globals = self.check_func.__globals__
  462.             self.check_func.__code__ = self.clone_func.__code__
  463.         else:
  464.             self.func_code = self.check_func.func_code
  465.             self.func_globals = self.check_func.func_globals
  466.             self.check_func.func_code = self.clone_func.func_code
  467.  
  468.     
  469.     def uninstall_clone(self):
  470.         if _IS_PYTHON_3:
  471.             self.check_func.__code__ = self.func_code
  472.         else:
  473.             self.check_func.func_code = self.func_code
  474.  
  475.     
  476.     def install_dt_self(self):
  477.         self.prev_func = self.dt_self._DocTestRunner__record_outcome
  478.         self.dt_self._DocTestRunner__record_outcome = self
  479.  
  480.     
  481.     def uninstall_dt_self(self):
  482.         self.dt_self._DocTestRunner__record_outcome = self.prev_func
  483.  
  484.     
  485.     def uninstall_module(self):
  486.         if self.del_module:
  487.             import sys
  488.             del sys.modules[self.del_module]
  489.             if '.' in self.del_module:
  490.                 (package, module) = self.del_module.rsplit('.', 1)
  491.                 package_mod = sys.modules[package]
  492.                 delattr(package_mod, module)
  493.             
  494.         
  495.  
  496.     
  497.     def __call__(self, *args, **kw):
  498.         self.uninstall_clone()
  499.         self.uninstall_dt_self()
  500.         del self.checker._temp_override_self
  501.         del self.checker._temp_call_super_check_output
  502.         result = self.prev_func(*args, **kw)
  503.         self.uninstall_module()
  504.         return result
  505.  
  506.     
  507.     def call_super(self, *args, **kw):
  508.         self.uninstall_clone()
  509.         
  510.         try:
  511.             return self.check_func(*args, **kw)
  512.         finally:
  513.             self.install_clone()
  514.  
  515.  
  516.  
  517.  
  518. def _find_doctest_frame():
  519.     import sys
  520.     frame = sys._getframe(1)
  521.     while frame:
  522.         l = frame.f_locals
  523.         if 'BOOM' in l:
  524.             return frame
  525.         
  526.         frame = frame.f_back
  527.     raise LookupError('Could not find doctest (only use this function *inside* a doctest)')
  528.  
  529. __test__ = {
  530.     'basic': '\n    >>> temp_install()\n    >>> print """<xml a="1" b="2">stuff</xml>"""\n    <xml b="2" a="1">...</xml>\n    >>> print """<xml xmlns="http://example.com"><tag   attr="bar"   /></xml>"""\n    <xml xmlns="...">\n      <tag attr="..." />\n    </xml>\n    >>> print """<xml>blahblahblah<foo /></xml>""" # doctest: +NOPARSE_MARKUP, +ELLIPSIS\n    <xml>...foo /></xml>\n    ' }
  531. if __name__ == '__main__':
  532.     import doctest
  533.     doctest.testmod()
  534.  
  535.